import os

from django.shortcuts import render,HttpResponseRedirect,HttpResponse

from Food import settings
from log_reg.models import *
from order.models import *
from eat.models import *
from django.db.transaction import atomic
from alipay import AliPay
import json, uuid, datetime
from django.db.models import F
from eat.views import order_T
from eat.views import order_F
from django.core.paginator import *



# Create your views here.
# 创建Alipay对象初始化参数(包含: 阿里的沙箱appid, 接收阿里传回的通知信息的链接, 商户自己的私钥, 阿里的公钥, 将项目的debug属性传送到对象里面去)
alipay = AliPay(appid='2016100900647057', app_notify_url='http://127.0.0.1:9000/order/pay_return',
                        app_private_key_path='my_private_key.txt',
                        alipay_public_key_path='alipay_public_key.txt',
                        return_url='http://127.0.0.1:8000/order/pay_return', debug=True)
def order(request):
    user = request.session.get('user')
    if not user:
        return HttpResponseRedirect('/logreg/log/')
    order_F()
    user = request.session.get('user')
    user = User.objects.get(username=user)
    order = user.order_1_set.all().order_by('-order_data')
    # 每页显示5条数据
    paginator = Paginator(order, 5)
    # 每次点击下一页/跳转所获取到的值
    page = request.GET.get('page')

    try:
        order = paginator.page(page)
    except PageNotAnInteger:
        # 如果传回的页数不是数字，则传递第一个页面。
        order = paginator.page(1)
    return render(request,'order.html',{'order':order})

# 订单
@atomic
def orderviews(request):
    if request.method == "GET":
        if not request.session.get('user'):
            return HttpResponseRedirect('/logreg/log/')

        user = request.session.get('user')
        user = User.objects.get(username=user)

        # 获取当前用户下的所有食品
        food_all = user.order_lingshi_set.all()
        # 总金额
        order_money = 0
        for i in food_all:
            order_money += i.food_money * i.food_num
        request.session['order_money'] = order_money
        user = request.session.get('user')
        user = User.objects.get(username=user)
        data = {'food_all': food_all, 'order_money': order_money,'user':user}
        request.session['data'] = data
        from eat.views import order_F
        order_F()
        return render(request, 'order_views.html', data)
    else:
        pay_def = request.POST.get('pay_def')
        address = User.objects.get(username=request.session.get('user')).address
        tel = User.objects.get(username=request.session.get('user')).tel
        data = request.session.get('data')

        if address == '0':
            error_address = '请点击下方 "去修改" 填写完整地址'
            data = {**{'error_address': error_address}, **data}
            return render(request, 'order_views.html', data)
        elif tel == '0':
            error_tel = '请点击下方 "去修改" 填写完整联系电话'
            data = {**{'error_tel': error_tel}, **data}
            return render(request, 'order_views.html', data)
        elif not pay_def:
            error_pay = '请至少选择一种支付方式'
            data = {**{'error_pay': error_pay},**data}
            return render(request, 'order_views.html', data)

        raw_order = {
            'address': User.objects.get(username=request.session.get('user')).address,  # 获取地址
            'tel': User.objects.get(username=request.session.get('user')).tel,  # 获取电话
            'payway': request.POST.get('pay_def','alipay'),  # 获取支付方式
            'order_id': uuid.uuid4().hex,  # 订单编号
            'user': User.objects.get(username=request.session.get('user')),  # 获取下单用户对象
            'order_user':request.session.get('user'), # 下单用户
            'order_money_all':request.session.get('order_money'), #订单总金额
        }
        # 将本次订单写入到数据库里
        order_1 = Order_1.objects.create(**raw_order)
        # 订单总金额
        total_amount = request.session.get('order_money')

        user = request.session.get('user')
        user = User.objects.get(username=user)
        # 获取当前用户下的所有食品
        food_all = user.order_lingshi_set.all()
        for i in food_all:

            # 将临时订单内容迁移到订单详情表
            order_1.order_2_set.create(Order_food=i.food_name,Order_num=i.food_num,food_money=i.food_num*i.food_money,Order_id=order_1.order_id,Order_data=order_1.order_data)


        # 清空当前用户下的临时订单(购物车),并且从总库存量减少
        for i in user.order_lingshi_set.all():
            Eat_Food.objects.filter(pk=i.eat_food).update(food_number=F('food_number')-i.food_num)
            i.delete()

        # 拿到前台传回的支付方式,进行判断是否为支付宝,如果不是,那就是微信,默认为支付宝

        if pay_def == 'alipay':
            params = alipay.direct_pay(subject='美食汇', total_amount=str(total_amount),
                                       out_trade_no=order_1.order_id)

            from Food.settings import DEBUG
            if DEBUG is True:
                # 沙箱网关
                url = 'https://openapi.alipaydev.com/gateway.do?' + params
            else:
                # 正式网关
                url = 'https://openapi.alipay.com/gateway.do?' + params

            return HttpResponseRedirect(url)
        else:
            # 微信支付
            from payjs import PayJS  # 也可根据个人习惯选择使用 Payjs/PAYJS/payjs
            from payjs import PayJSNotify  # 也可根据个人习惯选择使用 PayjsNotify/PAYJSNotify

            MCHID = '这里是商户号'
            KEY = '这里是商户密钥'

            # 回调url
            CALLBACK_URL = 'http://127.0.0.1:9000/order/pay_return'

            # 初始化
            p = PayJS(MCHID, KEY)

            # 扫码支付
            OUT_TRADE_NO = '2017TEST'  # 外部订单号（自己的支付系统的订单号，请保证唯一）
            TOTAL_FEE = 1  # 支付金额，单位为分，金额最低 0.01 元最多 10000 元
            BODY = '测试支付'  # 订单标题
            NOTIFY_URL = 'https://pay.singee.site/empty/'  # Notify 网址
            ATTACH = 'info'  # Notify 内容
            r = p.QRPay(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, body=BODY, notify_url=NOTIFY_URL, attach=ATTACH)
            if r:
                print(r.code_url)  # 二维码地址（weixin:// 开头，请使用此地址构建二维码）
                print(r.qrcode)  # 二维码地址（https:// 开头，为二维码图片的地址）
                print(r.payjs_order_id)  # 订单号（PAYJS 的）
            else:
                print(r.STATUS_CODE)  # HTTP 请求状态码
                print(r.ERROR_NO)  # 错误码
                print(r.error_msg)  # 错误信息
                print(r)

            # 构造收银台支付网址（仅构造链接，请使用浏览器 302 到这个网址，无法预检查调用是否成功）
            c = p.get_cashier_url(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, body=BODY, callback_url=CALLBACK_URL,notify_url=NOTIFY_URL, attach=ATTACH)
            print(c)

            # JSApi 支付
            OPENID = '这里填写支付用户的 OpenID'  # 支付用户在 PayJS 端的 OpenID，可通过 get_openid 获取
            j = p.JSApiPay(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, openid=OPENID, body=BODY,
                           notify_url=NOTIFY_URL, attach=ATTACH)
            if j:
                print(j.jsapi)  # 用于发起支付的支付参数
            else:
                print(j.STATUS_CODE)  # HTTP 请求状态码
                print(j.ERROR_NO)  # 错误码
                print(j.error_msg)  # 错误信息
                print(j)

            # 刷卡支付
            AUTH_CODE = '这里填写用户侧 18 位数字'  # 用户的支付条码或二维码所对应的数字
            m = p.MicroPay(out_trade_no=OUT_TRADE_NO, total_fee=TOTAL_FEE, auth_code=AUTH_CODE, body=BODY)
            print(m)

            # 订单查询
            s = p.check_status(payjs_order_id=r.payjs_order_id)
            if s:
                print(s.paid)  # 是否已支付
            else:
                print(s.error_msg)  # 错误信息
                print(s)

            # 订单关闭
            t = p.close(r.payjs_order_id)
            if t:
                print('Success')
            else:
                print('Error')
                print(t.return_msg)

            # 订单退款
            t = p.refund(r.payjs_order_id)
            if t:
                print('Success')
            else:
                print('Error')
                print(t.return_msg)

            # 获取用户 OpenId
            o = p.get_openid(callback_url=CALLBACK_URL)
            print(o)

            # 回调验证
            n = PayJSNotify(KEY, '回调内容（str 或 dict）')
            print(n)


# 支付成功与失败
def pay_return(request):
    # 需要编写代码的位置
    if request.method == 'GET':

        # 获取所有请求参数
        d = request.GET.dict()

        # 从请求参数中移除sign
        sign = d.pop('sign')
        # 验证签名

        if alipay.verify(d, sign):
            out_trade_no = d.get('out_trade_no')
            # 根据订单支付编号获取当前订单
            order = Order_1.objects.get(order_id=out_trade_no)
            # 修改订单状态
            if order.pay_case == '未支付':
                order.pay_case = '待发货'
                order.trade_no = d.get('trade_no')
                order.save()

        return HttpResponseRedirect('/order/')


# 购物车

def car(request):
    order_T()
    user = request.session.get('user')
    if not user:
        return HttpResponseRedirect('/logreg/log/')
    food_car = ''
    order_money = 0
    if user:
        user = User.objects.get(username=user)
        # 获取当前用户下的所有食品
        food_car = user.order_lingshi_set.all()
        # 总金额
        for i in food_car:
            order_money += i.food_money * i.food_num
        request.session['order_money'] = order_money

    return render(request,'order_car.html',{'food_car':food_car,'order_money':order_money,'user':user})

# 购物车减少增加操作
def car_jia_jian(request):
    user = request.session.get('user')
    user = User.objects.get(username=user)
    # 获取加减
    num = request.GET.get('num')
    # 获取食品的id
    food_id = request.GET.get('food_id')
    # 拿到该用户下的该食品对象
    food_del = user.order_lingshi_set.filter(eat_food=food_id)
    if num == 'jian':
        # 判断已购买数量是否为0,如果为0则直接删除
        if food_del[0].food_num <= 0:
            food_del.delete()
        else:
            food_del.update(food_num=F('food_num') - 1)
            # 减一之后再判断是否为0,如果是0则直接删除
            if food_del[0].food_num <= 0:
                food_del.delete()
    else:
        food_del.update(food_num=F('food_num') + 1)

    return HttpResponseRedirect('/order/car/')

def order_2(request):
    order_F()
    if request.method == 'GET':
        # 获取订单id
        orderid = request.GET.get('id')
        order = Order_1.objects.get(id = orderid)
        comment = order.comment_set.all()
        order_2 = order.order_2_set.all()
        Order_data = ''
        a = 0
        for i in order_2[0].Order_data:
            if a < 16:
                Order_data += i
                a += 1

        return render(request,'订单详情页.html',{'order_2_all':order_2,'Order_data':Order_data,'order_money_all':order.order_money_all,'orderid':orderid,'comment':comment})
    else:
        # 添加评论
        comment = request.POST.get('comment')
        photo = request.FILES.get('photo')
        photo_name = uuid.uuid4().hex
        lv = request.POST.get('lv',5)
        orderid = request.POST.get('orderid')
        user = request.session.get('user')
        user = User.objects.get(username=user)
        order = Order_1.objects.get(id = orderid)
        if photo:
            # 文件在服务器端的路径
            filepath = os.path.join(settings.MEDIA_ROOT,photo_name)
            with open(filepath, 'wb') as fp:
                for i in photo.chunks():
                    fp.write(i)

        user.comment_set.create(comment=comment,photo=photo_name,lv=int(lv),order_1=order)

        return HttpResponseRedirect('/order/')


def comment(request):
    order_T()
    comment = Comment.objects.all().order_by('-id').order_by('-lv')
    # 每页显示6条数据
    paginator = Paginator(comment, 6)
    # 每次点击下一页/跳转所获取到的值
    page = request.GET.get('page')

    try:
        comment = paginator.page(page)
    except PageNotAnInteger:
        # 如果传回的页数不是数字，则传递第一个页面。
        comment = paginator.page(1)
    return render(request,'comment.html',{'comment':comment})